package cc.mrbird.febs.weixin.IJPAY;

import cc.mrbird.febs.customer.entity.Activity;
import cc.mrbird.febs.customer.entity.Customer;
import cc.mrbird.febs.customer.entity.Income;
import cc.mrbird.febs.customer.entity.Order;
import cc.mrbird.febs.customer.service.IActivityService;
import cc.mrbird.febs.customer.service.ICustomerService;
import cc.mrbird.febs.customer.service.IIncomeService;
import cc.mrbird.febs.customer.service.IOrderService;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.ijpay.core.enums.SignType;
import com.ijpay.core.enums.TradeType;
import com.ijpay.core.kit.HttpKit;
import com.ijpay.core.kit.IpKit;
import com.ijpay.core.kit.WxPayKit;
import com.ijpay.wxpay.WxPayApi;
import com.ijpay.wxpay.WxPayApiConfig;
import com.ijpay.wxpay.WxPayApiConfigKit;
import com.ijpay.wxpay.model.UnifiedOrderModel;
import org.checkerframework.checker.units.qual.C;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>IJPay 让支付触手可及，封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。</p>
 *
 * <p>不依赖任何第三方 mvc 框架，仅仅作为工具使用简单快速完成支付模块的开发，可轻松嵌入到任何系统里。 </p>
 *
 * <p>IJPay 交流群: 723992875</p>
 *
 * <p>Node.js 版: https://gitee.com/javen205/TNWX</p>
 *
 * <p>微信支付 Demo</p>
 *
 * @author Javen
 */
@CrossOrigin(origins = "*",maxAge = 3600)
@Controller
@RequestMapping("/api/wxPay")
public class WxPayController extends AbstractWxPayApiController {
    private final Logger log = LoggerFactory.getLogger(this.getClass());

    @Autowired
    WxPayBean wxPayBean;

    @Resource
    private ICustomerService customerService;

    @Resource
    private IOrderService orderService;

    @Resource
    private IIncomeService incomeService;

    @Resource
    private IActivityService activityService;

    //支付异步回调地址
    private String notifyUrl;


    @Override
    public WxPayApiConfig getApiConfig() {
        WxPayApiConfig apiConfig;

        try {
            apiConfig = WxPayApiConfigKit.getApiConfig(wxPayBean.getAppId());
        } catch (Exception e) {
            apiConfig = WxPayApiConfig.builder()
                    .appId(wxPayBean.getAppId())
                    .mchId(wxPayBean.getMchId())
                    .partnerKey(wxPayBean.getPartnerKey())
                    .certPath(wxPayBean.getCertPath())
                    .domain(wxPayBean.getDomain())
                    .build();
        }
        //支付 完成回调异步通知地址
        notifyUrl = apiConfig.getDomain().concat("/api/wxPay/payNotify");
        return apiConfig;
    }

    @RequestMapping("")
    @ResponseBody
    public String index() {
        log.info("欢迎使用 IJPay 中的微信支付 -By Javen  <br/><br>  交流群：723992875");
        log.info(wxPayBean.toString());
        return ("欢迎使用 IJPay 中的微信支付 -By Javen  <br/><br>  交流群：723992875");
    }

    @GetMapping("/test")
    @ResponseBody
    public WxPayBean test() {
        return wxPayBean;
    }

    @GetMapping("/getKey")
    @ResponseBody
    public String getKey() {
        return WxPayApi.getSignKey(wxPayBean.getMchId(), wxPayBean.getPartnerKey(), SignType.MD5);
    }



    /**
     * 公众号支付
     */
    @CrossOrigin
    @RequestMapping(value = "/webPay", method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    public AjaxResult webPay(HttpServletRequest request,String openId,String trueName,String telephone,String body,String detail,Double total_fee,String activityId) {
        // openId，采用 网页授权获取 access_token API：SnsAccessTokenApi获取
//        String openId = (String) request.getSession().getAttribute("openid");
        if (openId == null) {
            return new AjaxResult().addError("当前下单账户为空！");
        }

        if (StrUtil.isEmpty(openId)) {
            return new AjaxResult().addError("openId is null");
        }
        String ip = IpKit.getRealIp(request);
        if (StrUtil.isEmpty(ip)) {
            ip = "127.0.0.1";
        }
        Double s = total_fee*100;
        Integer i = s.intValue();
        String s1 = i.toString();
        WxPayApiConfigKit.putApiConfig(getApiConfig());
        WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig();
        String out_trade_no = WxPayKit.generateStr();
        Map<String, String> params = UnifiedOrderModel
                .builder()
                .appid(wxPayApiConfig.getAppId())
                .mch_id(wxPayApiConfig.getMchId())
                .nonce_str(WxPayKit.generateStr())
                .body(body)
                .attach(out_trade_no) //附加数据
                .out_trade_no(out_trade_no)
                .total_fee(s1)
                .spbill_create_ip(ip)
                .notify_url(notifyUrl)
                .trade_type(TradeType.JSAPI.getTradeType())
                .openid(openId)
                .build()
                .createSign(wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256);

        String xmlResult = WxPayApi.pushOrder(false, params);
        log.info(xmlResult);

        Map<String, String> resultMap = WxPayKit.xmlToMap(xmlResult);
        String returnCode = resultMap.get("return_code");
        String returnMsg = resultMap.get("return_msg");
        if (!WxPayKit.codeIsOk(returnCode)) {
            return new AjaxResult().addError(returnMsg);
        }
        String resultCode = resultMap.get("result_code");
        if (!WxPayKit.codeIsOk(resultCode)) {
            return new AjaxResult().addError(returnMsg);
        }

        // 以下字段在 return_code 和 result_code 都为 SUCCESS 的时候有返回
        String prepayId = resultMap.get("prepay_id");

        Map<String, String> packageParams = WxPayKit.prepayIdCreateSign(prepayId, wxPayApiConfig.getAppId(),
                wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256);
        String jsonStr = JSONObject.toJSONString(packageParams);
//        String jsonStr = JSON.toJSONString(packageParams);

        //更新当前订单提交人
        customerService.update(new UpdateWrapper<Customer>().lambda()
                .set(Customer::getTrueName,trueName)
                .set(Customer::getMobile,telephone)
                .eq(Customer::getOpenid,openId));

        //创建订单
        Order order = new Order();
        order.setBody(body);
        order.setDetail(detail);
        order.setOpenId(openId);
        order.setOutTradeNo(out_trade_no);
        order.setTotalFee(new BigDecimal(total_fee));
        order.setSpbillCreateIp(ip);
        order.setTimeStart(LocalDateTime.now());
        order.setActivityId(activityId);
        orderService.save(order);
        return new AjaxResult().success(jsonStr);
    }

    /**
     * 异步通知
     */
    @CrossOrigin
    @RequestMapping(value = "/payNotify", method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    public String payNotify(HttpServletRequest request) {
        String xmlMsg = HttpKit.readData(request);
//        log.info("支付通知=" + xmlMsg);
        Map<String, String> params = WxPayKit.xmlToMap(xmlMsg);
        String returnCode = params.get("return_code");

        // 注意重复通知的情况，同一订单号可能收到多次通知，请注意一定先判断订单状态
        // 注意此处签名方式需与统一下单的签名类型一致
        if (WxPayKit.verifyNotify(params, WxPayApiConfigKit.getWxPayApiConfig().getPartnerKey(), SignType.HMACSHA256)) {
            if (WxPayKit.codeIsOk(returnCode)) {
                // 更新订单信息,将订单状态设置为已支付
                orderService.update(new UpdateWrapper<Order>().lambda()
                        .set(Order::getIsSuccess,1)
                        .eq(Order::getOutTradeNo,params.get("attach")));
                Order order = orderService.getOne(new QueryWrapper<Order>().lambda().eq(Order::getOutTradeNo, params.get("attach")));
                //获取支付的用户信息
                Customer customer = customerService.getOne(new QueryWrapper<Customer>().lambda().eq(Customer::getOpenid, params.get("openid")));

                Activity activity = activityService.getById(order.getActivityId());

                //添加代理商的收入详情
                if (customer.getPid()!=0) {
                    Income income = new Income();
                    income.setCustomerId(customer.getCustomerId());
                    income.setActivityName(order.getBody());
                    income.setCreateTime(LocalDateTime.now());
                    income.setDistribution(activity.getDistribution());
                    //计算收益
                    BigDecimal multiply = order.getTotalFee().multiply(new BigDecimal(0.0001)).multiply(new BigDecimal(activity.getDistribution()));
                    income.setIncomePrice(multiply);
                    income.setPid(customer.getPid());
                    income.setStatus(1);
                    income.setActivityId(activity.getTActivityId());
                    incomeService.save(income);

                    //更新用户收入详情
                    customerService.update(new UpdateWrapper<Customer>().lambda()
                            .set(Customer::getWallet, customer.getWallet().add(multiply))
                            .eq(Customer::getCustomerId, customer.getPid()));
                }
                // 发送通知等
                Map<String, String> xml = new HashMap<String, String>(2);
                xml.put("return_code", "SUCCESS");
                xml.put("return_msg", "OK");
                return WxPayKit.toXml(xml);
            }
        }
        return null;
    }

}
